package cn.hy.preparelesson.common.service;

import cn.hy.pms.thrift.utils.ThriftUtils;
import cn.hy.preparelesson.common.entity.*;
import cn.hy.preparelesson.common.enums.DataStatus;
import cn.hy.preparelesson.common.exception.MessageException;
import cn.hy.preparelesson.common.mapper.PlPostscriptMapper;
import cn.hy.preparelesson.common.params.PageParams;
import cn.hy.preparelesson.common.utils.IdUtils;
import cn.hy.preparelesson.common.utils.PageInfoUtils;
import cn.hy.preparelesson.common.utils.UserInfoUtils;
import cn.hy.preparelesson.common.utils.UserUtils;
import cn.hy.preparelesson.common.vo.PageInfo;
import cn.hy.preparelesson.common.vo.PlPostscriptListVo;
import cn.hy.preparelesson.common.vo.SysUserIdAndNameVo;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.thrift.TException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 后记 - 备课
 */
@Service
public class PlPostScriptService extends  BaseService {

    @Autowired
    PlPostscriptMapper plPostscriptMapper ;

    @Autowired
    PlLessonService plLessonService;

    @Autowired
    private PlLessonClassDetailService plLessonClassDetailService;

    @Autowired
    private PlFeedBackLessonDetailService plFeedBackLessonDetailService;


    /**
     * 根据schoolId, lessonId 查询备课 - 后记
     * @param schoolId
     * @param lessonId
     * @return
     */
    public PlPostscript findVaildPostScriptBySchoolIdAndLessonId(String schoolId, String lessonId) {
        PlPostscriptExample example = new PlPostscriptExample();
        example.createCriteria().andStatusEqualTo(DataStatus.NORMAL.getCode()).andSchoolIdEqualTo(schoolId).andLessonIdEqualTo(lessonId);
        List<PlPostscript> plPostscripts = plPostscriptMapper.selectByExampleWithBLOBs(example);
        return CollectionUtils.isEmpty(plPostscripts) ? null : plPostscripts.get(0);
    }


    /**
     * 根据schoolId， lessonIdList 查询 后记集合
     * @param schoolId
     * @param lessonIdList
     * @return
     */
    public List<PlPostscript> findValidListBySchoolIdAndLessonIdIn(String schoolId, List<String> lessonIdList){
        PlPostscriptExample example = new PlPostscriptExample();
        example.createCriteria().andSchoolIdEqualTo(schoolId)
                .andStatusEqualTo(DataStatus.NORMAL.getCode())
                .andLessonIdIn(lessonIdList);
       return  plPostscriptMapper.selectByExample(example);
    }

    /**
     * 查询后记详情
     * @param schoolId
     * @param id
     * @param lessonId
     * @param createBy
     * @return
     */
    public PlPostscript findValidBy(String schoolId, String id, String lessonId,  String createBy) {
        PlPostscriptExample example = new PlPostscriptExample();
        example.createCriteria().andSchoolIdEqualTo(schoolId)
                .andIdEqualTo(id).andLessonIdEqualTo(lessonId)
                .andCreateByEqualTo(createBy).andStatusEqualTo(DataStatus.NORMAL.getCode());
        List<PlPostscript> plPostscriptList = plPostscriptMapper.selectByExample(example);
        return CollectionUtils.isEmpty(plPostscriptList) ? null : plPostscriptList.get(0);

    }

    /**
     * 添加备课后记
     * @param schoolId
     * @param opeUserId
     * @param plPostscript
     */
    @Transactional(rollbackFor = Exception.class)
    public void save(String schoolId, String opeUserId, PlPostscript plPostscript) {
        Date now = new Date();
        plPostscript.setId(IdUtils.newId());
        plPostscript.setSchoolId(schoolId);
        plPostscript.setCreateAt(now);
        plPostscript.setUpdateAt(now);
        plPostscript.setCreateBy(opeUserId);
        plPostscript.setUpdateBy(opeUserId);
        plPostscript.setStatus(DataStatus.NORMAL.getCode());
        plPostscriptMapper.insert(plPostscript);
    }

    /**
     * 修改后记信息
     * @param schoolId
     * @param opeUserId
     * @param plPostscript
     */
    @Transactional(rollbackFor = Exception.class)
    public void update(String schoolId, String opeUserId, PlPostscript plPostscript) {
        PlPostscript curPostscript = findValidBy(schoolId, plPostscript.getId(), plPostscript.getLessonId(), opeUserId);
        if (curPostscript == null) {
            throw new MessageException("当前后记不存在或已被删除!");
        }
        curPostscript.setTitle(plPostscript.getTitle());
        curPostscript.setContent(plPostscript.getContent());
        curPostscript.setUpdateAt(new Date());
        plPostscriptMapper.updateByPrimaryKeyWithBLOBs(curPostscript);
     }

    /**
     * 查询后记详情
     * @param schoolId
     * @param lessonId
     * @param postscriptId
     * @return
     */
    public PlPostscript findValidPostscriptDetailBy(String schoolId, String lessonId, String postscriptId) {
        PlLesson checkPlLesson = plLessonService.findValidPlLessonBySchoolIdAndId(schoolId, lessonId);
        if (checkPlLesson == null){
            throw new MessageException("当前备课不存在或已被删除");
        }

        PlPostscriptExample example = new PlPostscriptExample();
        example.createCriteria().andStatusEqualTo(DataStatus.NORMAL.getCode())
                .andLessonIdEqualTo(lessonId).andSchoolIdEqualTo(schoolId)
                .andIdEqualTo(postscriptId);
        List<PlPostscript> plPostscriptList = plPostscriptMapper.selectByExampleWithBLOBs(example);
        return CollectionUtils.isEmpty(plPostscriptList) ? null : plPostscriptList.get(0);
    }

    /**
     * 分页获取评论信息 userId == null 则获取全校评论
     * @param schoolId
     * @param pageParams
     * @param title
     * @param createStartTime
     * @param createEndTime
     * @param subjectId
     * @param term
     * @param schoolYear
     * @param distanceYear
     * @param classId
     * @param createBy
     * @return
     */
    public PageInfo<PlPostscript> findPlPostscriptValidPageBy(String schoolId, PageParams pageParams, String title, Date createStartTime, Date createEndTime, String subjectId, Byte term, Integer schoolYear, BigDecimal distanceYear, String classId, String createBy) throws TException {
        List<String> plLessonIdList = plLessonService.findPlLessonIdListBy(schoolId, subjectId, term, schoolYear, distanceYear, classId, createBy);
        PageHelper.startPage(pageParams);
        PageInfo<PlPostscript> pageInfo = new PageInfo<>(findValidPlPostscriptListBy(schoolId, title, createStartTime, createEndTime, createBy, plLessonIdList));
        if(pageInfo.getList() != null && !CollectionUtils.isEmpty(pageInfo.getList())) {
           List<PlPostscript> plPostscriptList =  pageInfo.getList();

            //后记中 备课id集合
            List<String> postscriptLessonIdList = plPostscriptList.stream().map(PlPostscript::getLessonId).collect(Collectors.toList());



            //后记创建人Id集合
            List<String> userIdList = plPostscriptList.stream().map(PlPostscript::getCreateBy).collect(Collectors.toList());


            //年级班级集合
            List<PlLessonClassDetail> plClassList = plLessonClassDetailService.findPlCDListByLessonIdInAndBy(schoolId, postscriptLessonIdList, distanceYear,  classId);


            //备课集合
            List<PlLesson> plLessonList = plLessonService.findValidPlLessonListBy(schoolId, subjectId, schoolYear, term, postscriptLessonIdList, createBy);

            //我的后记创建人名字
            String currentUserRealName = null;
            if (StringUtils.isNotBlank(createBy)) {
                List<SysUserIdAndNameVo> currentUser = ThriftUtils.findUserNameByUserIdList(Arrays.asList(createBy));
                if(!CollectionUtils.isEmpty(currentUser)) {
                    currentUserRealName = currentUser.get(0).getName();
                    for (PlPostscript postscript : plPostscriptList) {
                        postscript.setCreateName(currentUserRealName);
                    }
                }
            } else {
                // 全校后记创建人名字
                UserInfoUtils.buildUserName(plPostscriptList, "getCreateBy", "setCreateName");
            }


            //备课 <-> 后记
            for (PlPostscript postscript : plPostscriptList) {
                PlLesson plLessonTemp =  plLessonList.stream().filter(lesson -> postscript.getLessonId().equals(lesson.getId())).findFirst().orElse(null);
                if (plLessonTemp != null) {
                   postscript.setSchoolYear(plLessonTemp.getSchoolYear());
                   postscript.setTerm(plLessonTemp.getTerm());
                   postscript.setLessonTitle(plLessonTemp.getTitle());
                   postscript.setSubjectName(plLessonTemp.getSubjectName());
                }
            }

            //班级 <-> 后记
            Map<String, List<PlLessonClassDetail>> classMapList = plClassList.stream().collect(Collectors.groupingBy(PlLessonClassDetail::getLessonId));
            for (Map.Entry<String, List<PlLessonClassDetail>> classMap : classMapList.entrySet()) {
                String tempLessonId = classMap.getKey();
                List<PlLessonClassDetail> classList = classMap.getValue();

                for (PlPostscript postscript : plPostscriptList) {
                    if (postscript.getLessonId().equals(tempLessonId)) {
                        String classNameStr = String.join(",", classList.stream().map(PlLessonClassDetail::getClassCode).collect(Collectors.toList()));
                        postscript.setClassNameStr(classNameStr);
                        postscript.setGradeName(Optional.ofNullable(classList.get(0).getGradeName()).orElse(null));
                    }
                }
            }

            // 查询备课是否有反馈
            List<PlFeedbackLessonDetail> pfbdList = plFeedBackLessonDetailService.findPFBDListBy(schoolId, postscriptLessonIdList);
            if (!CollectionUtils.isEmpty(pfbdList)) {
                for (PlPostscript postscript : plPostscriptList) {
                    PlFeedbackLessonDetail lessonFeedback = pfbdList.stream().filter(item -> item.getLessonId().equals(postscript.getLessonId())).findFirst().orElse(null);
                    if (lessonFeedback != null) {
                        postscript.setCanDelete(false);
                    } else {
                        postscript.setCanDelete(true);

                    }
                }
            }
        }
        return pageInfo;
    }


    /**
     * 分页获取评论信息
     * @param schoolId
     * @param pageParams
     * @param title
     * @param createStartTime
     * @param createEndTime
     * @param subjectId
     * @param term
     * @param schoolYear
     * @param distanceYear
     * @param classId
     * @return
     */
    @Deprecated
    public PageInfo<PlPostscriptListVo> findValidBy(String schoolId, PageParams pageParams, String title, Date createStartTime, Date createEndTime, String subjectId, Byte term, Integer schoolYear, BigDecimal distanceYear, String classId, String createBy) throws TException {
        List<PlPostscriptListVo> postscriptList = findValidPlLPostscriptList(schoolId, title,
                createStartTime, createEndTime, subjectId, term, schoolYear, distanceYear, classId, createBy);
        return PageInfoUtils.buildPageInfo(postscriptList, pageParams.getPageNum(), pageParams.getPageSize());
    }

    /**
     * 获取后记列表信息
     * @param schoolId
     * @param title
     * @param createStartTime
     * @param createEndTime
     * @param createBy
     * @return
     */
   public List<PlPostscript>  findValidPlPostscriptListBy(String schoolId, String title, Date createStartTime, Date createEndTime,  String createBy, List<String> lessonIdList) {
       PlPostscriptExample example = new PlPostscriptExample();
       PlPostscriptExample.Criteria criteria = example.createCriteria();
       criteria.andSchoolIdEqualTo(schoolId).andStatusEqualTo(DataStatus.NORMAL.getCode());
       if (StringUtils.isNotBlank(title)) {
           criteria.andTitleLike("%" + title + "%");
       }
       if (createStartTime != null) {
           criteria.andCreateAtGreaterThanOrEqualTo(createStartTime);
       }
       if (createEndTime != null) {
           criteria.andCreateAtLessThanOrEqualTo(createEndTime);
       }
       if (StringUtils.isNotBlank(createBy)) {
           criteria.andCreateByEqualTo(createBy);
       }
       if (!CollectionUtils.isEmpty(lessonIdList)) {
           criteria.andLessonIdIn(lessonIdList);
       }
       example.setOrderByClause("create_at desc");
      return plPostscriptMapper.selectByExampleWithBLOBs(example);
    }

    /**
     * 获取后记list
     * @param schoolId
     * @param title
     * @param createStartTime
     * @param createEndTime
     * @param subjectId
     * @param term
     * @param schoolYear
     * @param distanceYear
     * @param classId
     * @param createBy
     * @return
     */
    private List<PlPostscriptListVo> findValidPlLPostscriptList(String schoolId, String title, Date createStartTime, Date createEndTime, String subjectId, Byte term, Integer schoolYear, BigDecimal distanceYear, String classId, String createBy) throws TException {
       PlPostscriptExample example = new PlPostscriptExample();
       PlPostscriptExample.Criteria criteria = example.createCriteria();
       criteria.andSchoolIdEqualTo(schoolId).andStatusEqualTo(DataStatus.NORMAL.getCode());
       if (StringUtils.isNotBlank(title)) {
           criteria.andTitleLike("%" + title + "%");
       }
       if (createStartTime != null) {
           criteria.andCreateAtGreaterThanOrEqualTo(createStartTime);
       }
       if (createEndTime != null) {
           criteria.andCreateAtLessThanOrEqualTo(createEndTime);
       }
       if (StringUtils.isNotBlank(createBy)) {
           criteria.andCreateByEqualTo(createBy);
       }
       example.setOrderByClause("create_at desc");
        List<PlPostscript> plPostscriptList = plPostscriptMapper.selectByExampleWithBLOBs(example);
       if (CollectionUtils.isEmpty(plPostscriptList)) {
           return new ArrayList<>();
       }
       //后记中 备课id集合
       List<String> postscriptLessonIdList = plPostscriptList.stream().map(PlPostscript::getLessonId).collect(Collectors.toList());

       //后记创建人Id集合
       List<String> userIdList = plPostscriptList.stream().map(PlPostscript::getCreateBy).collect(Collectors.toList());
        List<SysUserIdAndNameVo> sysUserNameAndIdList = new ArrayList<>();
        if (StringUtils.isBlank(createBy)) {
           sysUserNameAndIdList = ThriftUtils.findUserNameByUserIdList(userIdList);
       }

       //年级班级集合
        List<PlLessonClassDetail> plClassList = plLessonClassDetailService.findPlCDListByLessonIdInAndBy(schoolId, postscriptLessonIdList, distanceYear,  classId);
        if (CollectionUtils.isEmpty(plClassList)) {
            return new ArrayList<>();
        }
        if (StringUtils.isNotBlank(classId)) {
            // 筛选条件包含classId
            List<String> lessonIdWidthClassIds = plClassList.stream().map(PlLessonClassDetail::getLessonId).collect(Collectors.toList());
            plClassList = plLessonClassDetailService.findPlCDListByLessonIdInAndBy(schoolId, lessonIdWidthClassIds, null , null);
        }
       //备课集合
        List<PlLesson> plLessonList = plLessonService.findValidPlLessonListBy(schoolId, subjectId, schoolYear, term, postscriptLessonIdList, createBy);
        if (CollectionUtils.isEmpty(plLessonList)) {
            return new ArrayList<>();
        }
        List<PlPostscriptListVo> plPostscriptListList = new ArrayList<>();
        //当前用户真实名字
        String currentUserRealName = null;
        if (StringUtils.isNotBlank(createBy)) {
            List<SysUserIdAndNameVo> currentUser = ThriftUtils.findUserNameByUserIdList(Arrays.asList(createBy));
            if(!CollectionUtils.isEmpty(currentUser)) {
                currentUserRealName = currentUser.get(0).getName();
            }
        }
        //后记 <-> 备课
        for (PlPostscript postscript : plPostscriptList) {
            PlLesson tempLesson = plLessonList.stream().filter(lesson -> postscript.getLessonId().equals(lesson.getId())).findFirst().orElse(null);
            PlLessonClassDetail plLessonClassDetail = plClassList.stream().filter(classLesson -> postscript.getLessonId().equals(classLesson.getLessonId())).findFirst().orElse(null);
            if (tempLesson !=null && plLessonClassDetail != null) {
                PlPostscriptListVo tempPlPostscript = new PlPostscriptListVo();
                BeanUtils.copyProperties(postscript, tempPlPostscript);
                tempPlPostscript.setSchoolYear(tempLesson.getSchoolYear());
                tempPlPostscript.setTerm(tempLesson.getTerm());
                tempPlPostscript.setLessonTitle(tempLesson.getTitle());
                tempPlPostscript.setSubjectName(tempLesson.getSubjectName());
               if (StringUtils.isNotBlank(createBy)) {
                   tempPlPostscript.setCreateName(currentUserRealName);
               } else {
                if (!CollectionUtils.isEmpty(sysUserNameAndIdList)) {
                    String userId = tempPlPostscript.getCreateBy();
                    SysUserIdAndNameVo tempSysUser = sysUserNameAndIdList.stream().filter(sysUser -> sysUser.getUserId().equals(userId)).findFirst().orElse(null);
                    if (tempSysUser != null) {
                        tempPlPostscript.setCreateName(tempSysUser.getName());
                    } else {
                        tempPlPostscript.setCreateBy("该账号已注销");
                    }
                } else {
                    tempPlPostscript.setCreateBy("该账号已注销");
                }
               }
                plPostscriptListList.add(tempPlPostscript);
            }
        }
        if (CollectionUtils.isEmpty(plPostscriptListList)) {
            return new ArrayList<>();
        }
        //班级 - 后记
        Map<String, List<PlLessonClassDetail>> classMapList = plClassList.stream().collect(Collectors.groupingBy(PlLessonClassDetail::getLessonId));
        for (Map.Entry<String, List<PlLessonClassDetail>> classMap : classMapList.entrySet()) {
            String tempLessonId = classMap.getKey();
            List<PlLessonClassDetail> classList = classMap.getValue();
            PlPostscriptListVo tempPlPostscriptVo = plPostscriptListList.stream().filter(plPostscriptListVo -> plPostscriptListVo.getLessonId().equals(tempLessonId)).findFirst().orElse(null);
            if (tempPlPostscriptVo != null) {
                String classNameStr = String.join(",", classList.stream().map(PlLessonClassDetail::getClassCode).collect(Collectors.toList()));
                tempPlPostscriptVo.setClassNameStr(classNameStr);
                tempPlPostscriptVo.setGradeName(Optional.ofNullable(classList.get(0).getGradeName()).orElse(null));
            }
        }

        // 查询备课是否有反馈
        List<PlFeedbackLessonDetail> pfbdList = plFeedBackLessonDetailService.findPFBDListBy(schoolId, postscriptLessonIdList);
        if (CollectionUtils.isEmpty(pfbdList)) {
            for (PlPostscriptListVo plPostscriptListVo : plPostscriptListList) {
                plPostscriptListVo.setCanDelete(true);
            }
        }
        for (PlPostscriptListVo plPostscriptListVo : plPostscriptListList) {
            PlFeedbackLessonDetail pfbl = pfbdList.stream().filter(item -> item.getLessonId().equals(plPostscriptListVo.getLessonId())).findFirst().orElse(null);
            if (pfbl == null) {
                plPostscriptListVo.setCanDelete(true);
            } else {
                plPostscriptListVo.setCanDelete(false);
            }
        }

        return  plPostscriptListList.stream().sorted(Comparator.comparing(PlPostscriptListVo::getCreateAt).reversed()).collect(Collectors.toList());
    }

    /**
     * 软删除后记信息
     * @param schoolId
     * @param postscriptId
     * @param lessonId
     */
    @Transactional(rollbackFor = Exception.class)
    public void softDelete(String schoolId, String postscriptId, String lessonId) {
        PlPostscript curPostscript = findValidPostscriptDetailBy(schoolId, lessonId, postscriptId);
        if (curPostscript == null) {
            throw new MessageException("当前后记不存在!");
        }
        if (!curPostscript.getCreateBy().equals(UserUtils.getUserId())) {
            throw new MessageException("您只能删除自己的后记!");
        }
        List<PlFeedbackLessonDetail> plFbLessonList = plFeedBackLessonDetailService.findListBySchoolIdAndLessonId(schoolId, lessonId);
        if (!CollectionUtils.isEmpty(plFbLessonList)) {
            throw new MessageException("当前后记关联的备课存在反馈不能删除！");
        }

        PlPostscript postscriptForUpdate = new PlPostscript();
        postscriptForUpdate.setId(curPostscript.getId());
        postscriptForUpdate.setUpdateAt(new Date());
        postscriptForUpdate.setUpdateBy(UserUtils.getUserId());
        postscriptForUpdate.setStatus(DataStatus.DELETE.getCode());
        plPostscriptMapper.updateByPrimaryKeySelective(postscriptForUpdate);
    }
}
